﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using GestionSaludOcupacional.Infrastructure.Mapping;
using GestionSaludOcupacional.Portal.Base;
using GestionSaludOcupacional.Portal.Base.Models;
using GestionSaludOcupacional.Repository;
using DbUser = UserBook.Repository;

namespace GestionSaludOcupacional.Infrastructure.Services
{
    [Export(typeof(IHealthService))]
    public class HealthService : IHealthService
    {
        [Import]
        public IMappingService MappingService { get; set; }

        [Import]
        public IUnitOfWork SaludOcupacionalUnitOfWork { get; set; }

        [Import]
        public DbUser.IUnitOfWork UsuarioUnitOfWork { get; set; }

        #region Implementation of IHealthService

        public IEnumerable<Individuo> ObtenerIndividuos()
        {
            return MappingService.GetAllModel(SaludOcupacionalUnitOfWork.IndividuoRepository.All());
        }

        public bool CrearCita(Cita cita)
        {
            var entity = MappingService.GetEntity(cita);
            using (SaludOcupacionalUnitOfWork)
            {
                SaludOcupacionalUnitOfWork.CitaRepository.Add(entity);
                return SaludOcupacionalUnitOfWork.Save();
            }
        }

        public Cita ObtenerCita(int id)
        {
            using (SaludOcupacionalUnitOfWork)
            {
                return MappingService.GetModel(SaludOcupacionalUnitOfWork.CitaRepository.Find(f => f.Id == id).FirstOrDefault());
            }
        }

        public IEnumerable<Cita> ObtenerCitas(int idIndividuo)
        {
            using (SaludOcupacionalUnitOfWork)
            {
                return MappingService.GetModel(SaludOcupacionalUnitOfWork.CitaRepository.All("Individuo,Medico").Where(f => f.IdIndividuo.Equals(idIndividuo)));
            }
        }

        public IEnumerable<Cita> ObtenerCitasExamen(string examen)
        {
            using (SaludOcupacionalUnitOfWork)
            {
                return MappingService.GetModel(SaludOcupacionalUnitOfWork.CitaRepository.All("Individuo,Medico").Where(f => f.TipoExamen.Equals(examen.ToUpper()) && f.Estado == 1).OrderByDescending(f => f.FechaCita));
            }
        }

        public int CrearHistoriaClinica(HistoriaClinica historiaClinica)
        {
            var entity = MappingService.GetEntity(historiaClinica);

            using (SaludOcupacionalUnitOfWork)
            {
                SaludOcupacionalUnitOfWork.HistoriaClinicaRepository.Add(entity);
                SaludOcupacionalUnitOfWork.Save();
            }
            return entity.Id;
        }

        public bool CrearIncidenteHistoria(HistoriaClinicaRegistro historiaClinicaRegistro)
        {
            var entity = MappingService.GetEntity(historiaClinicaRegistro);
            bool success;
            using (SaludOcupacionalUnitOfWork)
            {
                SaludOcupacionalUnitOfWork.HistoriaClinicaRegistroRepository.Add(entity);
                success = SaludOcupacionalUnitOfWork.Save();
            }
            return success;
        }

        public bool ActualizarIncidenteHistoria(HistoriaClinicaRegistro historiaClinicaRegistro)
        {
            var entity = MappingService.GetEntity(historiaClinicaRegistro);
            bool success;
            using (SaludOcupacionalUnitOfWork)
            {
                var original = ObtenerHistoriaClinicaRegistro(historiaClinicaRegistro.Id);
                /*No update idcita,idhistoria,idcentrotrabajo*/
                entity.IdCita = original.IdCita;
                entity.IdHistoria = original.IdHistoria;
                entity.IdCentroTrabajo = original.IdCentroTrabajo;
                entity.FechaCreacion = original.FechaCreacion;
                entity.FechaIngreso = original.FechaIngreso;
                SaludOcupacionalUnitOfWork.Context.HistoriaClinicaRegistroes.ApplyCurrentValues(entity);
                
                foreach(var item in entity.Anamnesis)
                {
                    /*no update fechacreacion*/
                    item.RegistroId = original.Anamnesis.First().RegistroId;
                    item.FechaCreacion = original.Anamnesis.First().FechaCreacion;                    
                    SaludOcupacionalUnitOfWork.Context.Anamnesis.ApplyCurrentValues(item);
                }
                foreach (var item in entity.AntecedentesEnfermedad)
                {
                    /*no update fechacreacion*/
                    item.RegistroId = original.AntecedentesEnfermedad.First().RegistroId;
                    item.FechaCreacion = original.AntecedentesEnfermedad.First().FechaCreacion;  
                    SaludOcupacionalUnitOfWork.Context.AntecedenteEnfermedads.ApplyCurrentValues(item);
                }
                foreach (var item in entity.FactoresRiesgo)
                {
                    /*no update fechacreacion*/
                    item.RegistroId = original.FactoresRiesgo.First().RegistroId;
                    item.FechaCreacion = original.FactoresRiesgo.First().FechaCreacion;  
                    SaludOcupacionalUnitOfWork.Context.FactorRiesgoes.ApplyCurrentValues(item);
                }
                foreach (var item in entity.ExamenesFisico)
                {
                    /*no update fechacreacion*/
                    item.RegistroId = original.ExamenesFisico.First().RegistroId;
                    SaludOcupacionalUnitOfWork.Context.ExamenFisicoes.ApplyCurrentValues(item);
                }

                success = SaludOcupacionalUnitOfWork.Save();
            }
            return success;
        }

        public HistoriaClinica ObtenerHistoriaClinica(int id)
        {
            var historia = SaludOcupacionalUnitOfWork.HistoriaClinicaRepository.Find(x => x.Id == id).FirstOrDefault();
            return MappingService.GetModel(historia);
        }

        public HistoriaClinica ObtenerHistoriaClinicaIndividuo(int idPaciente)
        {
            var historia = SaludOcupacionalUnitOfWork.HistoriaClinicaRepository.All("HistoriaClinicaRegistros").Where(x => x.IndividuoId == idPaciente).FirstOrDefault();
            var model = MappingService.GetModel(historia);
            return model;
        }

        public HistoriaClinicaRegistro ObtenerHistoriaClinicaRegistro(int registroId)
        {
            var historiaRegistro =
                SaludOcupacionalUnitOfWork.HistoriaClinicaRegistroRepository.All("ExamenesFisico,HistoriaClinica,Anamnesis,AntecedentesEnfermedad,FactoresRiesgo").Where(
                    x => x.Id == registroId).FirstOrDefault();
            var model = MappingService.GetModel(historiaRegistro);
            return model;
        }

        public IEnumerable<HistoriaClinicaRegistro> ObtenerHistoriaClinicaRegistrosByIndividuo(int individuoId)
        {
            var entity = SaludOcupacionalUnitOfWork.HistoriaClinicaRegistroRepository.All("HistoriaClinica").Where(x => x.HistoriaClinica.IndividuoId == individuoId).AsEnumerable();
            var models = MappingService.GetAllViewModel(entity);
            return models;
        }

        public bool CrearIndividuo(Individuo individuo)
        {
            var entity = MappingService.GetEntity(individuo);
            using (SaludOcupacionalUnitOfWork)
            {
                SaludOcupacionalUnitOfWork.IndividuoRepository.Add(entity);
                return SaludOcupacionalUnitOfWork.Save();
            }
        }

        public bool ActualizarIndividuo(Individuo individuo)
        {
            var entity = MappingService.GetEntity(individuo);
            using (SaludOcupacionalUnitOfWork)
            {
                SaludOcupacionalUnitOfWork.IndividuoRepository.Edit(entity, individuo.Id);
                return SaludOcupacionalUnitOfWork.Save();
            }
        }

        public Individuo ObtenerIndividuo(int id)
        {
            var entity = SaludOcupacionalUnitOfWork.IndividuoRepository.Find(f => f.Id == id).FirstOrDefault();
            return MappingService.GetModel(entity);
        }

        public IEnumerable<MedicoModel> ObtenerMedicos()
        {
            return MappingService.GetAllModel(SaludOcupacionalUnitOfWork.MedicoRepository.All());
        }

        public void CrearMedico(MedicoModel medico)
        {
            throw new NotImplementedException();
        }

        public MedicoModel ObtenerMedico(int id)
        {
            throw new NotImplementedException();
        }

        #endregion

        public bool GuardarExamenVision(ExamenVision examenVision)
        {
            var entity = MappingService.GetEntity(examenVision);
            using (SaludOcupacionalUnitOfWork)
            {
                if (examenVision.Id > 0)
                    SaludOcupacionalUnitOfWork.ExamenVisionRepository.Edit(entity, entity.Id);
                else
                    SaludOcupacionalUnitOfWork.ExamenVisionRepository.Add(entity);
                return SaludOcupacionalUnitOfWork.Save();
            }
        }

        public bool GuardarExamenPsicosensometria(ExamenPsicosensometria examenPsicosensometria)
        {
            var entity = MappingService.GetEntity(examenPsicosensometria);
            using (SaludOcupacionalUnitOfWork)
            {
                if (examenPsicosensometria.Id > 0)
                    SaludOcupacionalUnitOfWork.ExamenPsicosensometriaRepository.Edit(entity, entity.Id);
                else
                    SaludOcupacionalUnitOfWork.ExamenPsicosensometriaRepository.Add(entity);
                return SaludOcupacionalUnitOfWork.Save();
            }
        }

        public bool GuardarExamenPsicologia(ExamenPsicologia examenPsicologia)
        {
            var entity = MappingService.GetEntity(examenPsicologia);
            using (SaludOcupacionalUnitOfWork)
            {
                if (examenPsicologia.Id > 0)
                    SaludOcupacionalUnitOfWork.ExamenPsicologiaRepository.Edit(entity, entity.Id);
                else
                    SaludOcupacionalUnitOfWork.ExamenPsicologiaRepository.Add(entity);
                return SaludOcupacionalUnitOfWork.Save();
            }
        }

        public bool GuardarExamenAudicion(ExamenAudicion examenAudicion)
        {
            var entity = MappingService.GetEntity(examenAudicion);
            using (SaludOcupacionalUnitOfWork)
            {
                if (examenAudicion.Id > 0)
                    SaludOcupacionalUnitOfWork.ExamenAudicionRepository.Edit(entity, entity.Id);
                else
                    SaludOcupacionalUnitOfWork.ExamenAudicionRepository.Add(entity);
                return SaludOcupacionalUnitOfWork.Save();
            }
        }

        public ExamenVision ObtenerExamenVision(int id)
        {
            using (SaludOcupacionalUnitOfWork)
            {
                var examenVision = SaludOcupacionalUnitOfWork.ExamenVisionRepository.All("Individuo").FirstOrDefault(x => x.Id == id);
                return MappingService.GetEntity(examenVision);
            }
        }
        public IEnumerable<ExamenVision> ObtenerExamenVisionByIndividuo(int individuoId)
        {

            var examenVision = SaludOcupacionalUnitOfWork.ExamenVisionRepository.Find(x => x.IndividuoId == individuoId).ToList();
            return MappingService.GetEntity(examenVision);

        }

        public ExamenPsicosensometria ObtenerExamenPsicosensometria(int id)
        {
            using (SaludOcupacionalUnitOfWork)
            {
                var examenVision = SaludOcupacionalUnitOfWork.ExamenPsicosensometriaRepository.All("Individuo").FirstOrDefault(x => x.Id == id);
                return MappingService.GetEntity(examenVision);
            }
        }
        public IEnumerable<ExamenPsicosensometria> ObtenerExamenPsicosensometriaByIndividuo(int individuoId)
        {

            var examenVision = SaludOcupacionalUnitOfWork.ExamenPsicosensometriaRepository.Find(x => x.IndividuoId == individuoId).ToList();
            return MappingService.GetEntity(examenVision);

        }

        public ExamenPsicologia ObtenerExamenPsicologia(int id)
        {
            using (SaludOcupacionalUnitOfWork)
            {
                var examenVision = SaludOcupacionalUnitOfWork.ExamenPsicologiaRepository.All("Individuo").FirstOrDefault(x => x.Id == id);
                return MappingService.GetEntity(examenVision);
            }
        }
        public IEnumerable<ExamenPsicologia> ObtenerExamenPsicologiaByIndividuo(int individuoId)
        {

            var examenVision = SaludOcupacionalUnitOfWork.ExamenPsicologiaRepository.Find(x => x.IndividuoId == individuoId).ToList();
            return MappingService.GetEntity(examenVision);

        }

        public ExamenAudicion ObtenerExamenAudicion(int id)
        {
            using (SaludOcupacionalUnitOfWork)
            {
                var examenVision = SaludOcupacionalUnitOfWork.ExamenAudicionRepository.All("Individuo").FirstOrDefault(x => x.Id == id);
                return MappingService.GetEntity(examenVision);
            }
        }
        public IEnumerable<ExamenAudicion> ObtenerExamenAudicionByIndividuo(int individuoId)
        {
            var examenVision = SaludOcupacionalUnitOfWork.ExamenAudicionRepository.Find(x => x.IndividuoId == individuoId).ToList();
            return MappingService.GetEntity(examenVision);
        }
    }
}
